package com.zmn.oms.zmn.business.impl.order;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.base.channel.common.dro.ChannelDRO;
import com.zmn.base.channel.dubbo.interfaces.channel.ChannelListRemoteService;
import com.zmn.base.common.data.common.dro.area.AreaDRO;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.consts.GateTypeConsts;
import com.zmn.oms.business.interfaces.baidumap.BaiduMapBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.baidumap.LngLatLocation;
import com.zmn.oms.model.dto.order.create.CallCenterOrderCluesDTO;
import com.zmn.oms.model.dto.order.create.CreateOrderDTOH;
import com.zmn.oms.model.dto.order.zmn.ZsNormalNewOrderDTO;
import com.zmn.oms.model.dto.product.OrderProductDTO;
import com.zmn.oms.third.base.util.ProductIdUtil;
import com.zmn.oms.third.base.util.ThirdOrderUtil;
import com.zmn.oms.zmn.business.interfaces.order.CreateOrderBService;
import com.zmn.oms.zmn.normal.business.interfaces.order.ZsNormalOrderBService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 类描述：创建订单业务实现类
 *
 * @author lhl
 * @date 2020/02/01 14:38
 */
@Slf4j
@Service("createOrderBService")
public class CreateOrderBServiceImpl implements CreateOrderBService {

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private ChannelListRemoteService channelListRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private AreaListRemoteService areaListRemoteService;

    @Autowired
    private ZsNormalOrderBService zsNormalOrderBService;
    @Autowired
    private BaiduMapBService baiduMapBService;

    /**
     * 提取订单线索中的数据，并封装成录单对象
     * @param callCenterOrderCluesDTO
     * @return
     * @throws OmsBaseException
     */
    @Override
    public CreateOrderDTOH prepareCreateOrderByCallCenterOrderClues(CallCenterOrderCluesDTO callCenterOrderCluesDTO) throws OmsBaseException {
        CreateOrderDTOH createOrderDTOH = new CreateOrderDTOH();

        // 新单数据对象
        ZsNormalNewOrderDTO newOrderDTO = newStandardNewOrderDTOInstance();
        createOrderDTOH.setNewOrderDTO(newOrderDTO);

        // 默认下单入口: API-标准API(普通标准API)
        newOrderDTO.setReceiveEntranceId(GateTypeConsts.GATE_API_NORM);
        // 操作日志标识分类信息订单
        newOrderDTO.setOperatorRemark("【分类信息线索订单】");
        // 用户信息
        newOrderDTO.setUserName(callCenterOrderCluesDTO.getContactName());
        newOrderDTO.setTelephone(callCenterOrderCluesDTO.getTelephone());
        newOrderDTO.setStreet("");  // street字段在数据库中不能为空
        newOrderDTO.setAddress(callCenterOrderCluesDTO.getAddress());
        // 校验渠道ID
        {
            com.zmn.common.dto2.ResponseDTO<ChannelDRO> channelResponseDTO = channelListRemoteService.getByChannelId(callCenterOrderCluesDTO.getChannelId());
            ChannelDRO channelDRO = channelResponseDTO.getData();
            if (channelDRO == null) {
                throw new OmsBaseException(String.format("未找到对应的渠道，渠道ID: [%s]", callCenterOrderCluesDTO.getChannelId()));
            }
            newOrderDTO.setChannelId(callCenterOrderCluesDTO.getChannelId());
        }
        boolean isfindProductId = false;    // 标识是否解析到了产品ID
        // 解析产品信息，获取产品ID（使用前台产品）
        if (StringUtils.isNotBlank(callCenterOrderCluesDTO.getProduct())) {
            int showProductId = ProductIdUtil.queryShowProductIdByName(callCenterOrderCluesDTO.getProduct());

            OrderProductDTO orderProductDTO = newOrderDTO.getOrderProductList().get(0);
            orderProductDTO.setShowProductId(showProductId);
            orderProductDTO.setProductShowType(GlobalConsts.YES);
            newOrderDTO.setServCategId(GlobalConsts.SERV_CATEG_REPAIR);

            if (!Objects.equals(OrderConsts.CHANNEL_DISABLED_PRODUCT_ID, showProductId)) {
                isfindProductId = true;
            }
        }
        // 解析地址，获取城市ID和经纬度
        // 如果没解析到产品ID，则不需要解析地址了，使用默认产品和城市，改由客服人工处理
        if (isfindProductId && StringUtils.isNotBlank(callCenterOrderCluesDTO.getAddress())) {
            // 去掉空格和括号
            Pattern pattern = Pattern.compile("\\s+|（.*）|[(](.*)[)]");
            Matcher matcher = pattern.matcher(callCenterOrderCluesDTO.getAddress());
            String address = matcher.replaceAll("");


            LngLatLocation location = baiduMapBService.location(address);
            if (location != null) {
                // 使用经纬度确定城市ID
                Double lng = Double.valueOf(location.getLng());
                Double lat = Double.valueOf(location.getLat());
                try {
                    com.zmn.common.dto2.ResponseDTO<AreaDRO> areaResponse = areaListRemoteService.getAreaByLatAndLng(lng, lat);
                    AreaDRO areaDRO = areaResponse.getData();
                    if (areaDRO != null) {
                        // 城市ID
                        newOrderDTO.setCityId(areaDRO.getParentId());
                        // 找到城市ID，对应的经纬度才有意义
                        newOrderDTO.setLatitude(lat);
                        newOrderDTO.setLongitude(lng);
                    }
                } catch (Exception e) {
                    log.error("使用经纬度获取CityId失败: {}。 Longitude=[{}], Latitude=[{}]",
                            e.getMessage(), location.getLng(), location.getLat(), e);
                }
            }
        }
        // 预约时间
        {
            Date dutyTime = callCenterOrderCluesDTO.getDutyTime();
            // 如果没有预约时间，设置默认预约时间，取整点或半点。
            // 规则为：将当前时间作为参考时间 1.如果参考时间在0-8点之间，设置预约时间为当天10点；2.如果在18点以后，设
            // 置为第二天10点；3.如果在8-18点之间，取参考时间。
            if (dutyTime == null) {
                dutyTime = ThirdOrderUtil.getDefaultDutyTime();
            }

            newOrderDTO.setDutyTime(dutyTime);
        }
        // 备注信息
        newOrderDTO.setRemark(callCenterOrderCluesDTO.getRemark());

        // 日志记录经纬度信息
        if (newOrderDTO.getLongitude() != null && newOrderDTO.getLatitude() != null) {
            String latStr = String.format("经纬度：%s,%s", newOrderDTO.getLongitude(), newOrderDTO.getLatitude());
            if (StringUtils.isBlank(newOrderDTO.getOperatorLogRemark())) {
                newOrderDTO.setOperatorLogRemark(latStr);
            } else {
                newOrderDTO.setOperatorLogRemark(String.format("%s；%s", newOrderDTO.getOperatorLogRemark(), latStr));
            }
        }

        return createOrderDTOH;
    }

    @Override
    public OrderBO doCreateOrder(CreateOrderDTOH createOrderDTOH) throws OmsBaseException {
        log.info("[CreateOrderBService-createOrder] {}", JSON.toJSONString(createOrderDTOH.getNewOrderDTO()));

        OrderBO orderBO = zsNormalOrderBService.insertOrder(createOrderDTOH.getNewOrderDTO());
        return orderBO;
    }

    /**
     * 创建一个标准的录单对象。
     *  该对象只缺少以下必须补全的信息：
     *      1. 订单渠道来源
     *      2. 客户联系电话
     *      3. 下单入口
     * @return
     */
    private ZsNormalNewOrderDTO newStandardNewOrderDTOInstance() {
        ZsNormalNewOrderDTO newOrderDTO = new ZsNormalNewOrderDTO();

        // 用户信息
        //newOrderDTO.setTelephone();
        newOrderDTO.setGender(GlobalDict.GENDER_NO);
        // 基本信息
        //newOrderDTO.setChannelId();
        //newOrderDTO.setReceiveEntranceId(); // 下单入口
        newOrderDTO.setType(OrderConsts.ORDER_TYPE_NEW);
        newOrderDTO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        newOrderDTO.setDisableDiscard(GlobalConsts.NO);
        newOrderDTO.setOperator("系统");
        newOrderDTO.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
        newOrderDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
        newOrderDTO.setInputType(OrderConsts.ORDER_INPUT_TYPE_API);
        newOrderDTO.setServItemType(OrderConsts.SERVICE_ITEM_TYPE_ORDER);
        newOrderDTO.setReceiverManner(OrderConsts.RECEIVE_MANNER_API);
        // 默认产品
        newOrderDTO.setServCategId(GlobalConsts.SERV_CATEG_REPAIR);
        OrderProductDTO orderProduct = new OrderProductDTO();
        orderProduct.setShowProductId(OrderConsts.CHANNEL_DISABLED_PRODUCT_ID);
        orderProduct.setProductShowType(GlobalConsts.YES);
        orderProduct.setNumber(1);
        newOrderDTO.setOrderProductList(Lists.newArrayList(orderProduct));

        return newOrderDTO;
    }
}
